﻿package com.ghost.utils
{
	import flash.external.ExternalInterface;
	/**
	 * ... 外部容器交互工具类 ...
	 * @author Jerry
	 * @version 0.5.0
	 */
	public class ExternalInterfaceUtil
	{
		/** @private 函数名称记录列表（用于注销已注册的接口方法） */
		private static var _recordList:Array;
		
		/**
		 * 注册外部容器调用ActionScript的接口方法，将closure设为null则可删除回调注册
		 * @param	functionName 一个函数名称，JavaScript函数名称
		 * @param	closure 一个闭包函数，指定JavaScript调用的函数
		 */
		public static function addCallback(functionName:String, closure:Function):void
		{
			if (ExternalInterface.available) {
				try {
					ExternalInterface.addCallback(functionName, closure);
					if (closure) {
						addFunctionNameToList(functionName);
					} else {
						removeFunctionNameFromList(functionName);
					}
				} catch (e:Error) {
					throw "[异常错误]：" + e.message;
				} catch (e:SecurityError) {
					throw "[安全错误]：" + e.message;
				}
			} else {
				throw "[错误]：外部容器接口不可用！";
			}
		}
		
		/**
		 * ActionScript调用外部容器方法
		 * @param	functionName 一个字符串，外部容器中被AS调用的函数名
		 * @param	...rest 传递到容器中的参数
		 * @param	marshallExceptions 一个布尔值，指示播放器是否可以与外部容器间传递异常错误信息
		 * @return
		 */
		public static function call(functionName:String, ...rest):*
		{
			if (ExternalInterface.available) {
				try {
					rest.splice(0, 0, functionName);
					return ExternalInterface.call.apply(null, rest);
				} catch (e:Error) {
					throw "[异常错误]：" + e.message;
				} catch (e:SecurityError) {
					throw "[安全错误]：" + e.message;
				}
			} else {
				throw "[错误]：外部容器接口不可用！";
			}
		}
		
		/**
		 * 删除所有的回调函数注册
		 */
		public static function clearClosureFromList():void 
		{
			if (!_recordList) {
				return;
			}
			for each (var funcName:String in _recordList) 
			{
				addCallback(funcName, null);
			}
			_recordList = null;
		}
		
		/**
		 * 添加函数名称到列表中
		 * @private
		 * @param	functionName 一个字符串，需添加列表中的函数名
		 */
		private static function addFunctionNameToList(functionName:String):void 
		{
			if (!_recordList) {
				_recordList = [];
			}
			for each (var funcName:String in _recordList) 
			{
				if (funcName == functionName) {
					return;
				}
			}
			_recordList.push(functionName);
		}
		
		/**
		 * 从列表中删除指定函数名称
		 * @param	functionName
		 */
		private static function removeFunctionNameFromList(functionName:String):void 
		{
			if (!_recordList) {
				return;
			}
			for (var i:int = 0, length:int = _recordList.length; i < length; i++) 
			{
				if (_recordList[i] == functionName) {
					_recordList.splice(i, 1);
					return;
				}
			}
		}
		
		/**
		 * 设置一个布尔值，指示FlashPlayer与容器之前是否可以传递错误异常信息
		 */
		public static function set marshallExceptions(value:Boolean):void 
		{
			ExternalInterface.marshallExceptions = value;
		}
	}

}